﻿using CDFPreliminaryResults;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using DeepZoomPivotConstructor.PivotLib;
using t_TestingLibrary;
using System.ComponentModel.Composition;
using PaperRenderingInterfaces;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using t_PivotGeneratorTestHelpers;

namespace t_CDFPreliminaryResults
{
    
    
    /// <summary>
    ///This is a test class for ScanCDFIndexPageTest and is intended
    ///to contain all ScanCDFIndexPageTest Unit Tests
    ///</summary>
    [TestClass()]
    public class t_ScanBasicCDFIndexPage
    {
        [TestInitialize]
        public void TestSetup()
        {
            Utilities.MyClassInit();
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Utilities.MyClassDone();
        }

        /// <summary>
        /// Render a single image each time we are called.
        /// </summary>
        [Export(typeof(IPaperRenderEngine))]
        class DummyRender : IPaperRenderEngine
        {
            public List<string> allSeenAddresses = new List<string>();
            public System.Collections.Generic.IEnumerable<PivotImage> Render(string renderName, string renderAddress)
            {
                if (!allSeenAddresses.Contains(renderAddress) && renderName == "HTMLPlotPage")
                {
                    allSeenAddresses.Add(renderAddress);
                    PivotImage pmi = new PivotImage(null);
                    Trace.WriteLine("Rendering: " + renderName + " - " + renderAddress);
                    if (LocalTitle != null)
                    {
                        pmi.Add("Note Title", LocalTitle);
                    }
                    yield return pmi;
                }
            }

            string LocalTitle = null;

            internal void SetLocalTitle(string title)
            {
                LocalTitle = title;
            }
        }

        /// <summary>
        /// Hunt throught the metadata!
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="pmf"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private T1[] FindMetadata<T1>(PivotImage pmf, string p)
            where T1 : PivotMetadataBase
        {
            var md = from m in pmf
                     where m.Name == p && m.GetType() == typeof(T1)
                     let masType = (T1)m
                     where masType != null
                     select masType;
            return md.ToArray();
        }

        /// <summary>
        ///A test for ScanCDFIndexPage Constructor
        ///</summary>
        [TestMethod]
        public void ScanCDFIndexPageConstructorTest()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
        }

        [TestMethod]
        public void ScanExoticsPhysicsPageForAnalyses()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\exotic.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new DummyRender());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/exotic/exotic.html");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/exotic/exotic.html", laf.UrlAskedFor.ToString(), "Bad url was requested! Weird!");
            var results = result.ToArray();

            Assert.AreEqual(21, results.Length, "Expected this to try to scan 21 current analyses");

            CheckNoteTitle(results.First(), "Diphoton + X");
        }

        [TestMethod]
        public void ScanHiggsPhysicsPageForAnalyses()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\higgs.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new DummyRender());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/hdg/Results_files/widget1_markup.html");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/new/hdg/Results_files/widget1_markup.html", laf.UrlAskedFor.ToString(), "Bad url was requested! Weird!");
            var results = result.ToArray();

            Assert.AreEqual(25, results.Length, "Incorrect number of analyses found!");

            CheckNoteTitle(results.First(), "CDF combined search");
        }

        [TestMethod]
        public void ScanEWPhysicsPageForAnalyses()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\ew.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new DummyRender());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/ewk/");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/ewk/", laf.UrlAskedFor.ToString(), "Bad url was requested! Weird!");
            var results = result.ToArray();

            Assert.AreEqual(24, results.Length, "Incorrect number of analyses found!");

            CheckNoteTitle(results.First(), "W to pi gamma");
        }

        [TestMethod]
        public void TestNoCFiles()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\ew.html") };
            Utilities.AddPart(laf);
            DummyRender dmy = new DummyRender();
            Utilities.AddPart(dmy);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/ewk/");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/ewk/", laf.UrlAskedFor.ToString(), "Bad url was requested! Weird!");
            var results = result.ToArray();

            Assert.IsFalse(dmy.allSeenAddresses.Any(addr => addr.EndsWith(".C")), "Some url ends in .C - bad!");
            
        }

        [TestMethod]
        public void ScanTopMassPhysicsPageForAnalyses()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\top_mass.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new DummyRender());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/top/public_mass.html");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/new/top/public_mass.html", laf.UrlAskedFor.ToString(), "Bad url was requested! Weird!");
            var results = result.ToArray();

            Assert.AreEqual(17, results.Length, "Incorrect number of analyses found!");

            CheckNoteTitle(results.First(), "CDF & D0 Combination");
        }

        [TestMethod]
        public void ScanBPhysicsPageForAnalyses()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\B.html") };
            Utilities.AddPart(laf);
            var dr = new DummyRender();
            Utilities.AddPart(dr);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/bottom.html");
            Assert.IsTrue(result.Count() > 0, "Messed up the count");

            Assert.IsTrue(dr.allSeenAddresses.All(a => !a.Contains(".jpg")), "One of the sub pages we looked at contians a jpg file!");
            Assert.IsTrue(dr.allSeenAddresses.All(a => !a.Contains(".jpeg")), "One of the sub pages we looked at contians a jpg file!");
            Assert.IsTrue(dr.allSeenAddresses.All(a => !a.Contains(".png")), "One of the sub pages we looked at contians a jpg file!");
            Assert.IsTrue(dr.allSeenAddresses.All(a => !a.Contains(".ps")), "One of the sub pages we looked at contians a jpg file!");
            Assert.IsTrue(dr.allSeenAddresses.All(a => !a.Contains(".pdf")), "One of the sub pages we looked at contians a jpg file!");
        }

        [TestMethod]
        public void TestNoteTitleWhenSubPageKnowsIt()
        {
            ScanBasicCDFIndexPage target = new ScanBasicCDFIndexPage();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_CDFPreliminaryResults\\B.html") };
            Utilities.AddPart(laf);
            var dr = new DummyRender();
            dr.SetLocalTitle("this is a title");
            Utilities.AddPart(dr);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/bottom.html");

            var pmi = result.First();
            var titleMDs = from md in pmi
                           where md.Name == "Note Title"
                           let mdStr = md as PivotMetadataString
                           where mdStr != null
                           select mdStr.Value;

            Assert.AreEqual(1, titleMDs.Count(), "expect only a single title!");
            Assert.AreEqual("this is a title", titleMDs.First(), "The title didn't come back right!");
        }

        /// <summary>
        /// See if the title starts as we might expect it to start.
        /// </summary>
        /// <param name="pivotImage"></param>
        /// <param name="p"></param>
        private void CheckNoteTitle(PivotImage pmi, string initialTitleString)
        {
            var titles = FindMetadata<PivotMetadataString>(pmi, "Note Title");
            Assert.IsNotNull(titles);
            Assert.AreEqual(1, titles.Count(), "Expected one title");
            var t = titles.First();
            Assert.IsTrue(t.Value.StartsWith(initialTitleString), "Title '" + t.Value + "' did not start with '" + initialTitleString + "'.");
        }
    }
}
